package com.meeting.meetingroom_api.controller;

import com.meeting.meetingroom_api.dto.*;
import com.meeting.meetingroom_api.dto.UserRegistrationDto;
import com.meeting.meetingroom_api.dto.UserUpdateDto;
import com.meeting.meetingroom_api.dto.EmployeeApprovalDto;
import com.meeting.meetingroom_api.enums.UserRole;
import com.meeting.meetingroom_api.service.UserService;
import com.meeting.meetingroom_api.security.UserDetailsImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;
// import org.springframework.security.access.prepost.PreAuthorize; // For method-level security
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.data.domain.Sort;
import java.util.List;

@RestController
@RequestMapping("/api/users")
public class UserController {

    private final UserService userService;

    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }

    // Public endpoint for user registration (typically for customers)
    @PostMapping("/register")//已测试
    public ResponseEntity<UserDto> registerUser(@RequestBody UserRegistrationDto registrationDto) {
        // Default new registrations to CUSTOMER role if not specified or enforce it
        if (registrationDto.getRole() == null) {
            registrationDto.setRole(UserRole.customer);
        } else if (registrationDto.getRole() == UserRole.admin || registrationDto.getRole() == UserRole.employee) {
            // Potentially restrict self-registration as admin/employee without further auth
            // For now, let's assume this is handled by authorization rules if Spring Security is used
        }
        UserDto newUser = userService.registerUser(registrationDto);
        return new ResponseEntity<>(newUser, HttpStatus.CREATED);
    }


    /**
     * 管理员新增角色（需要传入角色名称 role：employee、admin、customer）
     */
    @PreAuthorize("hasRole('ADMIN')")
    @PostMapping("/admin/create")//已测试
    public ResponseEntity<UserDto> createUserByAdmin(@RequestBody UserRegistrationDto registrationDto) {
        UserDto newUser = userService.registerUser(registrationDto);
        return new ResponseEntity<>(newUser, HttpStatus.CREATED);
    }
    
    // @PreAuthorize("hasAnyRole('ADMIN', 'EMPLOYEE') or #userId == authentication.principal.id") // Example security
    @PreAuthorize("hasAnyRole('ADMIN', 'EMPLOYEE') or #userId == authentication.principal.id")
    @GetMapping("/{userId}")//已测试
    public ResponseEntity<UserDto> getUserById(@PathVariable Integer userId) {
        UserDto userDto = userService.getUserById(userId);
        return ResponseEntity.ok(userDto);
    }

    @GetMapping("/username/{username}")//已测试
    public ResponseEntity<UserDto> getUserByUsername(@PathVariable String username) {
        UserDto userDto = userService.getUserByUsername(username);
        return ResponseEntity.ok(userDto);
    }
    
    // @PreAuthorize("hasRole('ADMIN')")
    /**
     *  分页查询所有除管理员外的角色
     */
    //
    @PreAuthorize("hasRole('ADMIN')")
    @GetMapping
    public ResponseEntity<Page<UserDto>> getAllUsers(Pageable pageable) {
        Page<UserDto> users = userService.getAllUsers(pageable);
        return ResponseEntity.ok(users);
    }

    // @PreAuthorize("hasRole('ADMIN')")

    /**
     * 根据用户角色名称，分页查询对应的用户（客户或者员工）
     */
    //分页
    @PreAuthorize("hasRole('ADMIN')")
    @GetMapping("/role/{role}")
    public ResponseEntity<Page<UserDto>> getUsersByRole(@PathVariable UserRole role, Pageable pageable) {
        // 校验角色是否为客户或员工（防止查询管理员角色）
        if (role == UserRole.admin) {
            return ResponseEntity.badRequest().build();
        }
        Page<UserDto> users = userService.getUsersByRole(role, pageable);
        return ResponseEntity.ok(users);
    }

    // @PreAuthorize("hasAnyRole('ADMIN') or #userId == authentication.principal.id")

    /**
     * 管理员更新用户信息,包括状态等基础信息可以更新
     */
    @PreAuthorize("hasAnyRole('ADMIN') or #userId == authentication.principal.id")
    @PutMapping("/{userId}")//已测试
    public ResponseEntity<UserDto> updateUser(
            @PathVariable Integer userId, 
            @RequestBody UserUpdateDto userUpdateDto,
            @AuthenticationPrincipal UserDetailsImpl currentUser) {
        // 从token中获取当前用户ID，用于管理员操作的审计
        Integer adminIdForApproval = null;
        if (currentUser != null && 
            currentUser.getAuthorities().stream().anyMatch(a -> a.getAuthority().equals("ROLE_ADMIN"))) {
            adminIdForApproval = currentUser.getId();
        }
        UserDto updatedUser = userService.updateUser(userId, userUpdateDto, adminIdForApproval);
        return ResponseEntity.ok(updatedUser);
    }

    // @PreAuthorize("hasRole('ADMIN')")

    /**
     * 管理员删除用户
     */
    @PreAuthorize("hasRole('ADMIN')")
    @DeleteMapping("/{userId}")//已测试
    public ResponseEntity<Void> deleteUser(@PathVariable Integer userId) {
        userService.deleteUser(userId);
        return ResponseEntity.noContent().build();
    }

    // @PreAuthorize("hasRole('ADMIN')")

    /**
     * 管理员审核通过客户注册的账号
     */
    @PreAuthorize("hasRole('ADMIN')")
    @PostMapping("/{customerId}/approve")//已测试
    public ResponseEntity<UserDto> approveCustomer(
            @PathVariable Integer customerId,
            @AuthenticationPrincipal UserDetailsImpl currentUser) {
        UserDto approvedUser = userService.approveCustomerRegistration(customerId, currentUser.getId());
        return ResponseEntity.ok(approvedUser);
    }

    // @PreAuthorize("hasRole('ADMIN')")

    /**
     * 管理员修改客户或用户的状态active或frozen
     */
    @PreAuthorize("hasRole('ADMIN')")
    @PostMapping("/{userId}/status")//已测试
    public ResponseEntity<UserDto> changeAccountStatus(
            @PathVariable Integer userId, 
            @RequestParam String status,
            @AuthenticationPrincipal UserDetailsImpl currentUser) {
        UserDto updatedUser = userService.changeUserAccountStatus(userId, status, currentUser.getId());
        return ResponseEntity.ok(updatedUser);
    }

    /**
     * 获取所有待审核客户（分页）
     */
    @PreAuthorize("hasRole('ADMIN')")//已测试
    @GetMapping("/customers/pending")
    public ResponseEntity<Page<UserDto>> getPendingCustomers(
            @PageableDefault(size = 10, sort = "createdAt", direction = Sort.Direction.DESC) Pageable pageable) {
        Page<UserDto> pendingCustomers = userService.getPendingCustomers(pageable);
        return ResponseEntity.ok(pendingCustomers);
    }

    /**
     * 获取所有待审核客户（不分页）
     */
    @PreAuthorize("hasRole('ADMIN')")//已测试
    @GetMapping("/customers/pending/all")
    public ResponseEntity<List<UserDto>> getAllPendingCustomers() {
        List<UserDto> pendingCustomers = userService.getPendingCustomers();
        return ResponseEntity.ok(pendingCustomers);
    }

    /**
     * 管理员拒绝客户注册申请
     */
    @PreAuthorize("hasRole('ADMIN')")
    @PostMapping("/{customerId}/reject")//已测试
    public ResponseEntity<String> rejectCustomerRegistration(
            @PathVariable Integer customerId,
            @RequestParam(required = false) String rejectionReason,
            @AuthenticationPrincipal UserDetailsImpl currentUser) {
        userService.rejectCustomerRegistration(customerId, currentUser.getId(), rejectionReason);
        return ResponseEntity.ok("客户注册申请已拒绝并删除用户记录");
    }

    /**
     * 获取活跃中的用户或员工（分页）
     */
    @PreAuthorize("hasRole('ADMIN')")
    @GetMapping("/active")
    public ResponseEntity<Page<UserDto>> getActiveUsers(
            @PageableDefault(size = 10, sort = "createdAt", direction = Sort.Direction.DESC) Pageable pageable) {
        Page<UserDto> activeUsers = userService.getActiveUsers(pageable);
        return ResponseEntity.ok(activeUsers);
    }

    /**
     * 获取活跃中的特定角色用户（分页）
     * @param role 用户角色：customer 或 employee
     */
    @PreAuthorize("hasRole('ADMIN')")
    @GetMapping("/active/{role}")//已测试
    public ResponseEntity<Page<UserDto>> getActiveUsersByRole(
            @PathVariable UserRole role,
            @PageableDefault(size = 10, sort = "createdAt", direction = Sort.Direction.DESC) Pageable pageable) {
        // 校验角色是否为客户或员工（防止查询管理员角色）
        if (role == UserRole.admin) {
            return ResponseEntity.badRequest().build();
        }
        Page<UserDto> activeUsers = userService.getActiveUsersByRole(role, pageable);
        return ResponseEntity.ok(activeUsers);
    }

    /**
     * 获取冻结的用户或员工（分页）
     */
    @PreAuthorize("hasRole('ADMIN')")//已测试
    @GetMapping("/frozen")
    public ResponseEntity<Page<UserDto>> getFrozenUsers(
            @PageableDefault(size = 10, sort = "createdAt", direction = Sort.Direction.DESC) Pageable pageable) {
        Page<UserDto> frozenUsers = userService.getFrozenUsers(pageable);
        return ResponseEntity.ok(frozenUsers);
    }

    /**
     * 获取冻结的特定角色用户（分页）
     * @param role 用户角色：customer 或 employee
     */
    @PreAuthorize("hasRole('ADMIN')")
    @GetMapping("/frozen/{role}")//已测试
    public ResponseEntity<Page<UserDto>> getFrozenUsersByRole(
            @PathVariable UserRole role,
            @PageableDefault(size = 10, sort = "createdAt", direction = Sort.Direction.DESC) Pageable pageable) {
        // 校验角色（防止查询管理员角色）
        if (role == UserRole.admin) {
            return ResponseEntity.badRequest().build();
        }
        Page<UserDto> frozenUsers = userService.getFrozenUsersByRole(role, pageable);
        return ResponseEntity.ok(frozenUsers);
    }
    
    // ==================== 员工审核相关接口 ====================
    
    /**
     * 获取所有待审核员工（分页）
     */
    @PreAuthorize("hasRole('ADMIN')")
    @GetMapping("/employees/pending")
    public ResponseEntity<Page<UserDto>> getPendingEmployees(
            @PageableDefault(size = 10, sort = "createdAt", direction = Sort.Direction.DESC) Pageable pageable) {
        Page<UserDto> pendingEmployees = userService.getPendingEmployees(pageable);
        return ResponseEntity.ok(pendingEmployees);
    }

    /**
     * 获取所有待审核员工（不分页）
     */
    @PreAuthorize("hasRole('ADMIN')")
    @GetMapping("/employees/pending/all")
    public ResponseEntity<List<UserDto>> getAllPendingEmployees() {
        List<UserDto> pendingEmployees = userService.getPendingEmployees();
        return ResponseEntity.ok(pendingEmployees);
    }

    /**
     * 管理员审核通过员工注册申请
     */
    @PreAuthorize("hasRole('ADMIN')")
    @PostMapping("/{employeeId}/approve-employee")
    public ResponseEntity<UserDto> approveEmployee(
            @PathVariable Integer employeeId,
            @AuthenticationPrincipal UserDetailsImpl currentUser) {
        UserDto approvedEmployee = userService.approveEmployeeRegistration(employeeId, currentUser.getId());
        return ResponseEntity.ok(approvedEmployee);
    }

    /**
     * 管理员拒绝员工注册申请
     */
    @PreAuthorize("hasRole('ADMIN')")
    @PostMapping("/{employeeId}/reject-employee")
    public ResponseEntity<String> rejectEmployee(
            @PathVariable Integer employeeId,
            @RequestParam(required = false) String rejectionReason,
            @AuthenticationPrincipal UserDetailsImpl currentUser) {
        userService.rejectEmployeeRegistration(employeeId, currentUser.getId(), rejectionReason);
        return ResponseEntity.ok("员工注册申请已拒绝并删除用户记录");
    }

    /**
     * 管理员统一审核员工注册申请（通过或拒绝）
     */
    @PreAuthorize("hasRole('ADMIN')")
    @PostMapping("/employees/review")
    public ResponseEntity<?> reviewEmployeeRegistration(
            @RequestBody EmployeeApprovalDto approvalDto,
            @AuthenticationPrincipal UserDetailsImpl currentUser) {
        if (approvalDto.isApproved()) {
            UserDto reviewedEmployee = userService.approveEmployeeRegistration(approvalDto.getEmployeeId(), currentUser.getId());
            return ResponseEntity.ok(reviewedEmployee);
        } else {
            userService.rejectEmployeeRegistration(
                approvalDto.getEmployeeId(), 
                currentUser.getId(), 
                approvalDto.getRejectionReason()
            );
            return ResponseEntity.ok("员工注册申请已拒绝并删除用户记录");
        }
    }

}